package com.bsc.mina.service;

import com.bsc.minacommand.common.CommandState;
import static com.bsc.minacommand.common.CommandState.ROOT;
import com.bsc.minacommand.model.BscCommand;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.statemachine.annotation.IoHandlerTransition;
import org.apache.mina.statemachine.context.AbstractStateContext;
import static org.apache.mina.statemachine.event.IoHandlerEvents.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DefaultHandler extends CommandState {

    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultHandler.class);

    static class ServerContext extends AbstractStateContext {
    }

    @IoHandlerTransition(on = SESSION_CREATED, in = CONNECTED)
    public void created(IoSession session) {
        LOGGER.info("socket创建" + session.getId());
    }

    //当连接被创建并打开调用
    //设置连接状态起始为Not_connected,虽然实际已连接服务器，但为登陆故状态为notconnected.自定义概念。
    @IoHandlerTransition(on = SESSION_OPENED, in = CONNECTED)
    public void connect(IoSession session) {
        LOGGER.info("socket建立连接" + session.getId());
    }

    //Mina发生异常是调用
    //起始状态为root代表对所有事件都起作用，权重为10相对较高，优先调用。
    @IoHandlerTransition(on = EXCEPTION_CAUGHT, in = ROOT, weight = 10)
    public void exceptionCaught(IoSession session, Exception e) {
        LOGGER.warn("Mina发生异常.", e);
    }

    @IoHandlerTransition(on = MESSAGE_RECEIVED, in = ROOT)
    public void messageReceived(IoSession session, Object message)
            throws Exception {
        LOGGER.debug("Unexpected message, drop it.");
    }

    @IoHandlerTransition(on = MESSAGE_SENT, in = ROOT)
    public void messageSent(IoSession session, Object message)
            throws Exception {
        LOGGER.debug("Command \"{}\" sent success.", ((BscCommand)message).CommandName());
    }

    @IoHandlerTransition(in = ROOT, weight = 100)
    public void unhandledEvent() {
        LOGGER.warn("Unhandled event.");
    }

    @IoHandlerTransition(on = SESSION_IDLE, in = ROOT)
    public void sessionIdle(IoSession session) {
        session.close(true);
        LOGGER.warn("client Idle session");
    }

    @IoHandlerTransition(on = SESSION_CLOSED, in = ROOT)
    public void sessionClosed(IoSession session) {
        LOGGER.warn("close client session");
    }
}
